package cn.com.cifi.mars.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.com.cifi.mars.bean.bo.SysLogBO;
import cn.com.cifi.mars.bean.dto.ProjectOrgDto;
import cn.com.cifi.mars.bean.vo.price.ApproveWarnConfirmInfoVO;
import cn.com.cifi.mars.bean.vo.price.PriceApproveWarnConfirmTodoVO;
import cn.com.cifi.mars.bean.vo.price.PriceApproveWarnInfoVO;
import cn.com.cifi.mars.bean.vo.price.PriceApproveWarnTodoVO;
import cn.com.cifi.mars.common.exception.MsgException;
import cn.com.cifi.mars.constant.ApprovedStateCodeEnum;
import cn.com.cifi.mars.constant.CodeEnum;
import cn.com.cifi.mars.constant.IsSuccessEnum;
import cn.com.cifi.mars.constant.LogEventEnum;
import cn.com.cifi.mars.constant.LogSrcEnum;
import cn.com.cifi.mars.constant.LogTypeEnum;
import cn.com.cifi.mars.constant.WarnPossitionTypeEnum;
import cn.com.cifi.mars.constant.WhetherEnum;
import cn.com.cifi.mars.entity.ApprovalBill;
import cn.com.cifi.mars.entity.ApprovalWarning;
import cn.com.cifi.mars.entity.ApprovalWarningPosition;
import cn.com.cifi.mars.entity.ApprovalWarningSupervise;
import cn.com.cifi.mars.entity.MdmProject;
import cn.com.cifi.mars.entity.PortalTodo;
import cn.com.cifi.mars.entity.common.IdmUser;
import cn.com.cifi.mars.mapper.mars.ApprovalBillMapper;
import cn.com.cifi.mars.mapper.mars.ApprovalWarningMapper;
import cn.com.cifi.mars.mapper.mars.ApprovalWarningSuperviseMapper;
import cn.com.cifi.mars.mapper.mars.IdmUserMapper;
import cn.com.cifi.mars.mapper.mars.PortalTodoMapper;
import cn.com.cifi.mars.mapper.mars.ProjectMapper;
import cn.com.cifi.mars.mapper.mars.SysDictionaryMapper;
import cn.com.cifi.mars.service.ApprovalWarningService;
import cn.com.cifi.mars.service.SysLogService;
import cn.com.cifi.mars.util.BasicAuthClient;
import cn.com.cifi.mars.util.DateUtils;
import cn.com.cifi.mars.util.LocalDateTimeUtils;
import cn.com.cifi.mars.util.StrUtils;
import cn.com.cifi.mars.util.UUIDUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 货值审批预警表 服务实现类
 * </p>
 *
 * @author yyd
 * @since 2021-03-19
 */
@Slf4j
@Service
public class ApprovalWarningServiceImpl extends ServiceImpl<ApprovalWarningMapper, ApprovalWarning> implements ApprovalWarningService {

	@Autowired
	ApprovalWarningMapper approvalWarningMapper;
	
	@Autowired
	ApprovalWarningSuperviseMapper approvalWarningSuperviseMapper;
	
	@Autowired
    ProjectMapper projectMapper;
	
	@Autowired
    IdmUserMapper idmUserMapper;
	
	@Autowired
	PortalTodoMapper portalTodoMapper;
	
	@Autowired
	SysDictionaryMapper sysDictionaryMapper;
	
	@Autowired
	ApprovalBillMapper approvalBillMapper;
	
	@Autowired
    SysLogService sysLogService;
	
	@Value("${warning_sys_code}")
	private String warningSysCode;
	
	@Value("${warning_type}")
	private String warningType;
	
	@Value("${warning_supervise_login_url}")
	private String warningSuperviseLoginUrl;
	
	@Value("${warning_supervise_api_key}")
	private String warningSuperviseApiKey;
	
	@Value("${warning_supervise_api_value}")
	private String warningSuperviseApiValue;
	
	@Value("${warning_supervise_create_url}")
	private String warningSuperviseCreateUrl;
	
	@Value("${warning_supervise_feedback_url}")
	private String warningSuperviseFeedbackUrl;
	
	public static final BigDecimal DEFAULT_DRIFT_RATE = new BigDecimal(0.03);
	
	@Override
	public void save(String projectId,String billId,PriceApproveWarnInfoVO approveWarnInfoVO) {
		ApprovalWarning approvalWarning = approvalWarningMapper.selectByBillId(billId);
		if(approvalWarning != null) {
			approvalWarning.setBillId(billId);
			approvalWarning.setProjectId(projectId);
			approvalWarning.setWarnFlag(approveWarnInfoVO.getWarnFlag());
			approvalWarning.setIsPresident(approveWarnInfoVO.getIsPresident());
			approvalWarning.setConfirmFlag(approveWarnInfoVO.getConfirmFlag());
			approvalWarning.setContent(JSON.toJSONString(approveWarnInfoVO));
			approvalWarning.setUpdateTime(LocalDateTime.now());
			approvalWarningMapper.updateById(approvalWarning);
		}else {
			approvalWarning = new ApprovalWarning();
			approvalWarning.setId(UUIDUtils.create());
			approvalWarning.setBillId(billId);
			approvalWarning.setProjectId(projectId);
			approvalWarning.setWarnFlag(approveWarnInfoVO.getWarnFlag());
			approvalWarning.setIsPresident(approveWarnInfoVO.getIsPresident());
			approvalWarning.setConfirmFlag(approveWarnInfoVO.getConfirmFlag());
			approvalWarning.setContent(JSON.toJSONString(approveWarnInfoVO));
			approvalWarning.setCreateTime(LocalDateTime.now());
			approvalWarning.setUpdateTime(LocalDateTime.now());
			approvalWarningMapper.insert(approvalWarning);
		}
	}

	@Override
	public PriceApproveWarnTodoVO getPriceApproveWarnTodo(String instanceId) {
		ApprovalWarning approvalWarning = approvalWarningMapper.selectByTaskId(instanceId);
		PriceApproveWarnTodoVO result = new PriceApproveWarnTodoVO();
		if(approvalWarning != null) {
			MdmProject project = approvalWarningMapper.selectProject(approvalWarning.getProjectId());
			PortalTodo pt = portalTodoMapper.selectById(instanceId);
			String projectName = project == null ? "" : project.getProjectName();
			String name= "";
			String title = "【货值审批预警】 ";
			if(pt != null) {
				name= pt.getTitle();
			}else {
				name = title+ projectName;
			}
			result.setName(name);
			result.setTodoStatus(pt != null ? pt.getTodoStatus() : "");
			result.setBillUrl(approvalWarning.getBillUrl());
			PriceApproveWarnInfoVO vo = JSON.parseObject(approvalWarning.getContent(), PriceApproveWarnInfoVO.class);
			if(vo != null) {
				result.setBulidWarnInfoList(vo.getBulidWarnInfoList());
				result.setCoreWarnInfoList(vo.getCoreWarnInfoList());
				result.setBulletinWarnInfo(vo.getBulletinWarnInfo());
			}
		}
		return result;
	}
	
	@Override
	public synchronized PriceApproveWarnConfirmTodoVO getPriceApproveWarnConfirmTodo(IdmUser user,String instanceId,String userId) {
		ApprovalWarningSupervise approvalWarningSupervise = approvalWarningSuperviseMapper.selectByTaskId(instanceId);
		PriceApproveWarnConfirmTodoVO result = new PriceApproveWarnConfirmTodoVO();
		if(approvalWarningSupervise != null) {
			ApprovalWarning approvalWarning = approvalWarningMapper.selectById(approvalWarningSupervise.getWarningId());
			MdmProject project = approvalWarningMapper.selectProject(approvalWarning.getProjectId());
			PortalTodo pt = portalTodoMapper.selectById(instanceId);
			String projectName = project == null ? "" : project.getProjectName();
			result.setName("【货值风险专项质询下发确认】"+projectName);
			result.setProjectName(projectName);
			result.setTodoStatus(pt != null ? pt.getTodoStatus() : "");
			PriceApproveWarnInfoVO vo = JSON.parseObject(approvalWarning.getContent(), PriceApproveWarnInfoVO.class);
			if(vo != null) {
				result.setBulidWarnInfoList(vo.getBulidWarnInfoList());
				result.setCoreWarnInfoList(vo.getCoreWarnInfoList());
				result.setBulletinWarnInfo(vo.getBulletinWarnInfo());
			}
			
			result.setIsSend(approvalWarningSupervise.getIsSend());
			result.setPosition(getPosition(user,userId));
			result.setMarketingSuggest(approvalWarningSupervise.getMarketingState());
			result.setMarketingOpinionDesc(approvalWarningSupervise.getMarketingOpinionDesc());
			result.setOperationSuggest(approvalWarningSupervise.getOperationState());
			result.setOperationOpinionDesc(approvalWarningSupervise.getOperationOpinionDesc());
			
			ApproveWarnConfirmInfoVO warnConfirmInfo = new ApproveWarnConfirmInfoVO();
			warnConfirmInfo.setFillPeople(approvalWarningSupervise.getFillName());
			warnConfirmInfo.setOverseePeople(approvalWarningSupervise.getSuperviseName());
			warnConfirmInfo.setByOverseePeople(approvalWarningSupervise.getBeSuperviseName());
			warnConfirmInfo.setTaskSource(approvalWarningSupervise.getTaskSource());
			warnConfirmInfo.setMainFunction(approvalWarningSupervise.getHostFunction());
			warnConfirmInfo.setFeedbackLoop(approvalWarningSupervise.getBackPeriod());
			warnConfirmInfo.setPriority(approvalWarningSupervise.getPriority());
			warnConfirmInfo.setFinishTime(LocalDateTimeUtils.formatTime(approvalWarningSupervise.getFinishTime(), DateUtils.DATE_FULL_STR));
			warnConfirmInfo.setCompletionCriteria(approvalWarningSupervise.getStandard());
			warnConfirmInfo.setCompletionCriteriaDesc(approvalWarningSupervise.getStandardDesc());
			warnConfirmInfo.setFinishAsk(approvalWarningSupervise.getFinishAsk());
			warnConfirmInfo.setUrl(approvalWarningSupervise.getBillUrl());
			
			result.setWarnConfirmInfo(warnConfirmInfo);
		}
		return result;
	}

	private String getPosition(IdmUser user,String userId) {
		if(StrUtils.isEmpty(userId)) {
			userId = user.getAlias();
		}
		return approvalWarningSuperviseMapper.selectUserPosition(userId,WarnPossitionTypeEnum.WARN_CONFIRM.getKey());
	}

	@Override
	public void sendWarnSupervise(IdmUser user, String instanceId) {
		ApprovalWarningSupervise approvalWarningSupervise = approvalWarningSuperviseMapper.selectByTaskId(instanceId);
		if(approvalWarningSupervise != null) {
            if(approvalWarningSupervise.getIsSend() != null && approvalWarningSupervise.getIsSend().intValue() == 1) {
                CodeEnum.INTERNAL_ERROR.setMessage("督办已创建，不允许重复发送");
                    throw new MsgException(CodeEnum.INTERNAL_ERROR);
            }
			if(StrUtils.isEmpty(approvalWarningSupervise.getMarketingState()) || StrUtils.isEmpty(approvalWarningSupervise.getMarketingOpinionDesc())) {
				CodeEnum.INTERNAL_ERROR.setMessage("营销意见未反馈");
	   		 	throw new MsgException(CodeEnum.INTERNAL_ERROR);
			}
			if(StrUtils.isEmpty(approvalWarningSupervise.getOperationState()) || StrUtils.isEmpty(approvalWarningSupervise.getOperationOpinionDesc())) {
				CodeEnum.INTERNAL_ERROR.setMessage("请先保存意见，再发起督办");
	   		 	throw new MsgException(CodeEnum.INTERNAL_ERROR);
			}
			
			if(StrUtils.isEmpty(approvalWarningSupervise.getBeSuperviseAccount())) {
				CodeEnum.INTERNAL_ERROR.setMessage("被督办人为空，不允许发送督办");
	   		 	throw new MsgException(CodeEnum.INTERNAL_ERROR);
			}
			
			if(StrUtils.isEmpty(approvalWarningSupervise.getFinishAsk())) {
				CodeEnum.INTERNAL_ERROR.setMessage("督办完成要求为空，不允许发送督办");
	   		 	throw new MsgException(CodeEnum.INTERNAL_ERROR);
			}
			
			String token= getSuperviseToken(getFillUser());
			BasicAuthClient bac = new BasicAuthClient();
			if(StrUtils.isNotEmpty(token)) {
				String createParam = prepareCreateParam(instanceId,user,approvalWarningSupervise);
				//创建督办
				log.info("########创建督办请求接口参数："+createParam);
				String createResult = bac.postData(warningSuperviseCreateUrl,createParam,warningSuperviseApiKey, warningSuperviseApiValue,token);
				log.info("########创建督办请求接口响应数据："+createResult);
                saveLog("货值审批预警","创建督办接口调用","创建督办请求接口参数："+createParam+";"+"创建督办请求接口响应数据："+createResult,user.getAlias());
				if(StrUtils.isNotEmpty(createResult)) {
					JSONObject createJsonObject=JSONObject.parseObject(createResult);
					String code = createJsonObject.getString("code");
					if(code.equals("2000")) {
						approvalWarningSupervise.setIsSend(WhetherEnum.YES.getKey());
						approvalWarningSupervise.setFinishTime(LocalDateTime.now().plusDays(7));
						approvalWarningSuperviseMapper.updateById(approvalWarningSupervise);
						
						//运营-反馈督办
						String operationToken= getSuperviseToken(approvalWarningSupervise.getOperationBy());
						String operationFeedbackParam = prepareFeedbackParam(createJsonObject,approvalWarningSupervise.getOperationOpinionDesc());
						log.info("########运营反馈督办请求接口参数："+operationFeedbackParam);
						String operationFeedbackResult = bac.postData(warningSuperviseFeedbackUrl, operationFeedbackParam,warningSuperviseApiKey, warningSuperviseApiValue,operationToken);
						log.info("########运营反馈督办请求接口响应数据："+operationFeedbackResult);
						saveLog("货值审批预警","反馈督办接口调用","运营反馈督办请求接口参数："+operationFeedbackParam+";"+"反馈督办请求接口响应数据："+operationFeedbackResult,user.getAlias());
						
						//营销-反馈督办
						String marketingToken= getSuperviseToken(approvalWarningSupervise.getMarketingBy());
						String marketingFeedbackParam = prepareFeedbackParam(createJsonObject,approvalWarningSupervise.getMarketingOpinionDesc());
						log.info("########营销反馈督办请求接口参数："+operationFeedbackParam);
						String marketingFeedbackResult = bac.postData(warningSuperviseFeedbackUrl, marketingFeedbackParam,warningSuperviseApiKey, warningSuperviseApiValue,marketingToken);
						log.info("########营销反馈督办请求接口响应数据："+marketingFeedbackResult);
						saveLog("货值审批预警","反馈督办接口调用","营销反馈督办请求接口参数："+marketingFeedbackParam+";"+"反馈督办请求接口响应数据："+marketingFeedbackResult,user.getAlias());
					
					}else {
						 CodeEnum.INTERNAL_ERROR.setMessage("创建督办请求接口失败");
		        		 throw new MsgException(CodeEnum.INTERNAL_ERROR);
					}
				}
			}else {
				 CodeEnum.INTERNAL_ERROR.setMessage("创建督办请求接口失败，获取不到token值");
        		 throw new MsgException(CodeEnum.INTERNAL_ERROR);
			}
		}else {
			CodeEnum.INTERNAL_ERROR.setMessage("货值风险专项质询下发确认实例不存在");
			throw new MsgException(CodeEnum.INTERNAL_ERROR);
		}
	}

	private String getFillUser() {
		String account = "";
		List<ApprovalWarningPosition> list = approvalWarningMapper.selectByType(WarnPossitionTypeEnum.INFORMANT.getKey());
		if(CollectionUtils.isNotEmpty(list)) {
			account = list.get(0).getPositionNum();
		}
		return account;
	}
	
	private String getSuperviseToken(String account) {
		String token="";
		BasicAuthClient bac = new BasicAuthClient();
		String url = warningSuperviseLoginUrl+"?"+"sysCode="+warningSysCode+"&username="+account;
		log.info("########获取督办Token请求参数："+url);
		String result = bac.getData(url, warningSuperviseApiKey, warningSuperviseApiValue);
		log.info("########获取督办Token响应数据："+result);
		if(StrUtils.isNotEmpty(result)) {
			JSONObject jsonObject=JSONObject.parseObject(result);
			String code = jsonObject.getString("code");
			if(code.equals("2000")) {
				token = jsonObject.getString("data");
			}
		}
		return token;
	}

	private String prepareCreateParam(String instanceId,IdmUser user,ApprovalWarningSupervise approvalWarningSupervise) {
		JSONArray array = new JSONArray();
		JSONObject jsonObject= new JSONObject();
		LocalDateTime finishDateTime = approvalWarningSupervise.getFinishTime();
		LocalDateTime now = LocalDateTime.now().plusDays(14);
		LocalDateTime finishTime = null;
		if(now.isAfter(finishDateTime)) {
			finishTime = LocalDateTime.now().plusDays(14);
		}else {
			finishTime = finishDateTime;
		}
		MdmProject project = approvalWarningMapper.selectProject(approvalWarningSupervise.getProjectId());
		jsonObject.put("taskName", project.getProjectName()+"-货值审批预警督办");
		jsonObject.put("taskSource", approvalWarningSupervise.getTaskSource());
		jsonObject.put("taskLevel", approvalWarningSupervise.getPriority());
		jsonObject.put("superviseBy", approvalWarningSupervise.getSuperviseAccount());
		jsonObject.put("hostBy", approvalWarningSupervise.getBeSuperviseAccount());
		jsonObject.put("assistantBy", getAssistantBy(approvalWarningSupervise.getProjectId()));
		jsonObject.put("observerBy", getObserverBy(approvalWarningSupervise.getProjectId()));
		jsonObject.put("taskType", approvalWarningSupervise.getHostFunction());
		jsonObject.put("feedbackType", approvalWarningSupervise.getBackPeriod());
		jsonObject.put("feedbackValue", Integer.valueOf(approvalWarningSupervise.getBackPeriodCount()));
		jsonObject.put("taskAsk", approvalWarningSupervise.getStandard());
		jsonObject.put("createBy", user.getAlias());
		jsonObject.put("createdDate", LocalDateTimeUtils.formatTime(LocalDateTime.now(), DateUtils.DATE_FULL_STR));
		jsonObject.put("remark", prepareRemark(approvalWarningSupervise));
		jsonObject.put("taskStatus", "执行中");
		jsonObject.put("projectId", approvalWarningSupervise.getProjectId());
		jsonObject.put("projectName", "");
		jsonObject.put("projectRemark", "");
        jsonObject.put("taskDeadline",LocalDateTimeUtils.formatTime(finishTime, DateUtils.DATE_FULL_STR));
		jsonObject.put("userId", user.getAlias());
		jsonObject.put("systemCode", warningSysCode);
		jsonObject.put("eventType", warningType);
        jsonObject.put("extend01", approvalWarningSupervise.getUniqId());
		array.add(jsonObject);
		return array.toJSONString();
	}
	
	private String prepareRemark(ApprovalWarningSupervise approvalWarningSupervise) {
		return approvalWarningSupervise.getStandardDesc()+
				"<br>督办完成要求：<br>"+approvalWarningSupervise.getFinishAsk()+
				"<br>数据来源："+"<a href="+approvalWarningSupervise.getBillUrl()+" target='_blank' style = 'color:#2761ff'>点击查看货值审批单</a>";
	}
	
	private String prepareFeedbackParam(JSONObject createObject,String info) {
		JSONObject jsonObject= new JSONObject();
		JSONArray arr = createObject.getJSONArray("data");
		JSONObject object=  arr.getJSONObject(0);
		jsonObject.put("progress", object.getString("progress"));
		jsonObject.put("taskId", object.getString("id"));
		jsonObject.put("taskName", object.getString("taskName"));
		jsonObject.put("instanceId", "");
		jsonObject.put("todoId", "");
		jsonObject.put("info", info);
	    return jsonObject.toJSONString();
	}
	
	private Object getObserverBy(String projectId) {
		ProjectOrgDto org = projectMapper.selectProjectParentData(projectId);
		String groupId="";
		String regionId="";
		String result="";
		StringBuilder sb = new StringBuilder();
		if(org != null) {
			regionId=org.getRegionId();
			groupId = org.getGroupId();
		}
		List<ApprovalWarningPosition> list = approvalWarningMapper.selectByType(WarnPossitionTypeEnum.WARN_NOTITY.getKey());
		List<String> rPositionGroupIds = new ArrayList<>();
		List<String> gPositionGroupIds = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(list)) {
			list.forEach(x->{
				if(x.getLevel().equals("区域")) {
					rPositionGroupIds.add(x.getPositionNum());
				}else {
					gPositionGroupIds.add(x.getPositionNum());
				}
			});
		}
		List<IdmUser> userList = idmUserMapper.selectRegionPrincipal(rPositionGroupIds,gPositionGroupIds,regionId,groupId);
		if(CollectionUtils.isNotEmpty(userList)) {
			userList.forEach(x->{
				sb.append(x.getAlias()).append(",");
			});
			result = sb.toString().substring(0, sb.toString().length()-1);
		}
		return result;
	}
	
	private String getAssistantBy(String projectId) {
		ProjectOrgDto org = projectMapper.selectProjectParentData(projectId);
		String regionId="";
		String result="";
		StringBuilder sb = new StringBuilder();
		if(org != null) {
			regionId=org.getRegionId();
		}
		List<ApprovalWarningPosition> list = new ArrayList<>();
		if(regionId.equals("10270000")) {
			list = approvalWarningMapper.selectByType(WarnPossitionTypeEnum.ASSISTANT_BY_SD.getKey());
		}else {
			list = approvalWarningMapper.selectByType(WarnPossitionTypeEnum.ASSISTANT_BY.getKey());
		}
		List<String> positionGroupIds = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(list)) {
			list.forEach(x->{
				positionGroupIds.add(x.getPositionNum());
			});
		}
		List<IdmUser> userList = idmUserMapper.selectRegionUser(positionGroupIds,regionId);
		if(CollectionUtils.isNotEmpty(userList)) {
			userList.forEach(x->{
				sb.append(x.getAlias()).append(",");
			});
			result = sb.toString().substring(0, sb.toString().length()-1);
		}
		return result;
	}

    private boolean saveLog(String module,String title,String content,String userName) {
		SysLogBO bo = new SysLogBO();
		bo.setEvent(LogEventEnum.BROWSE);
    	bo.setSource(LogSrcEnum.PC);
    	bo.setModule(module);
    	bo.setTitle(title);
    	bo.setContent(content);
    	bo.setType(LogTypeEnum.ZERO.getKey());
    	bo.setIsSuccess(IsSuccessEnum.SUCCESS.getKey());
        return sysLogService.add(bo,userName);
	}
	

}
